/*******************************************************************************
 * Copyright (c) 2012, 2013 XML-Print Project.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     XML-Print Project - initial API and implementation
 ******************************************************************************/
package info.xmlprint.ui.stileditor;

import info.xmlprint.action.CmdToPDF;
import info.xmlprint.core.mapping.GeneralLayout;
import info.xmlprint.core.mapping.MappingGroup;
import info.xmlprint.core.project.PrintProject;
import info.xmlprint.core.xml.PElementGroup;
import info.xmlprint.run.RuntimeUtil;
import info.xmlprint.run.WorkbenchInfo;
import info.xmlprint.run.XML2Foplus;
import info.xmlprint.ui.format.FormatGroupSetup;
import info.xmlprint.ui.innerlink.InnerLinkSetup;
import info.xmlprint.ui.mapping.MappingGroupSetup;
import info.xmlprint.ui.message.GuiMessages;
import info.xmlprint.ui.referencesystem.PageMasterSetup;
import info.xmlprint.ui.referencesystem.ReferenceFieldSetup;
import info.xmlprint.ui.referencesystem.ReferencingSystemSetup;
import info.xmlprint.util.FileUtil;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;

/*
 * StileditorViewer ist Container fuer ein MappingGroupViewer und ein FormatGroupViewer
 * updateViewer aktualisiert MappingGroupViewer/FormatGroupViewer, sobald MappingGroupViewer/FormatGroupViewer Aenderungen hat
 */

public class StileditorViewer {
	private static StileditorViewer stileditorViewer;

	public static StileditorViewer getInstance() {
		if (stileditorViewer == null) {
			synchronized (StileditorViewer.class) {
				if (stileditorViewer == null) {
					stileditorViewer = new StileditorViewer();
				}
			}
		}
		return stileditorViewer;
	}

	// Composite for setup FormatGroup
	private FormatGroupSetup formatGroupSetup;

	// private ReferencingSystemGroup referencingSystemGroup;

	// private FormatGroup formatGroup;
	private MappingGroup mappingGroup;
	// private ReferenceFieldGroup refereceFieldGroup;

	// Composite for setup MappingGroup
	private MappingGroupSetup mappingGroupSetup;
	
	// Struktur des Xml-Datei, beschreibt, welche Attribute und Werte jedes
	// Element besizt.
	private PElementGroup pElementGroup;

	private PrintProject printProject;

	private ReferenceFieldSetup referenceFieldSetup;

	// Composite for setup Reference
	private ReferencingSystemSetup referencingSystemSetup;

	// GUI for setup seitenlayout
	private PageMasterSetup pageMasterSetup;

	private InnerLinkSetup innerLinkSetup;

	private Shell shell;

	private boolean stop;

	private StileditorViewer() {
		initGui();
	}

	public PrintProject getPrintProject() {
		return printProject;
	}

	public void initGui() {
		shell = new Shell(Display.getDefault(), SWT.CLOSE | SWT.MIN
				| SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX);

		shell.setText(GuiMessages.Stileditor_Gui_Title);
		shell.setLayout(new GridLayout());
		setMainMenu(shell);

		ScrolledComposite scrolledComposite = new ScrolledComposite(shell,
				SWT.H_SCROLL | SWT.V_SCROLL);
		scrolledComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

		// main Composite
		Composite mainComp = new Composite(scrolledComposite, SWT.NONE);
		mainComp.setLayout(new GridLayout());

		SashForm sashForm = new SashForm(mainComp, SWT.TOP | SWT.BORDER);
		sashForm.setLayoutData(new GridData());
		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));

		final List leftList = new List(sashForm, SWT.NONE);
		leftList.setItems(new String[] { GuiMessages.General_Gui_Mappings,
				GuiMessages.General_Gui_Formats,
				GuiMessages.Fieldinformation_FieldDefinition,
				GuiMessages.Stileditor_Gui_ReferencingSystem, GuiMessages.Stileditor_Gui_PageLayout, GuiMessages.Stileditor_Gui_InnerLink }); //$NON-NLS-N$

		final Composite rightComp = new Composite(sashForm, SWT.NONE);
		rightComp.setLayoutData(new GridData(GridData.FILL_BOTH));

		final StackLayout stackLayout = new StackLayout();
		rightComp.setLayout(stackLayout);

		leftList.select(0);
		leftList.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				switch (leftList.getSelectionIndex()) {
				case 0:
					mappingGroupSetup.updateControl();
					stackLayout.topControl = mappingGroupSetup;
					break;
				case 1:
					formatGroupSetup.updateControl();
					stackLayout.topControl = formatGroupSetup;
					break;
				case 2:
					referenceFieldSetup.updateControl();
					stackLayout.topControl = referenceFieldSetup;
					break;
				case 3:
					referencingSystemSetup.updateControl();
					stackLayout.topControl = referencingSystemSetup;
					break;
				case 4:
					pageMasterSetup.updateControl();
					stackLayout.topControl = pageMasterSetup;
					break;
					
				case 5:
					innerLinkSetup.updateControl();
					stackLayout.topControl = innerLinkSetup;
					break;
				default:
				}
				rightComp.layout();

			}
		});
		mappingGroupSetup = new MappingGroupSetup(rightComp, SWT.NONE);
		formatGroupSetup = new FormatGroupSetup(rightComp, SWT.NONE);
		referencingSystemSetup = new ReferencingSystemSetup(rightComp, SWT.NONE);
		referenceFieldSetup = new ReferenceFieldSetup(rightComp, SWT.NONE);
		pageMasterSetup = new PageMasterSetup(rightComp, SWT.NONE);
		
		innerLinkSetup = new InnerLinkSetup(rightComp, SWT.NONE);

		// foot Composite
		setFootComp(shell);
		sashForm.setWeights(new int[] { 1, 4 });
		scrolledComposite.setExpandHorizontal(true);
		scrolledComposite.setExpandVertical(true);
		scrolledComposite.setContent(mainComp);

		stackLayout.topControl = mappingGroupSetup;

		shell.addListener(SWT.Close, new Listener() {
			@Override
			public void handleEvent(Event event) {
				shell.setVisible(false);
				event.doit = false;
				WorkbenchInfo.focusEditor();
			}
		});

		shell.setSize(800, 600);
		FileUtil.shellSetCenter(shell);
		shell.layout();
		// shell.setMaximized(true); //TODO: Always maximized?
		// shell.open();
		// while (!shell.isDisposed()) {
		// if (!display.readAndDispatch())
		// display.sleep();
		// }
		// display.dispose();
	}

	/**
	 * read value of mappingGroup, formatGroup, reference... clone values and
	 * use them for preview
	 */
	private void initInput() {
		// reset stop
		stop = false;

		printProject = RuntimeUtil.getInstance().getCurrentPrintProject();

		if (printProject == null) {
			stop = true;
			return;
		}

		printProject = printProject.getClone();
		if (printProject == null) {
			stop = true;
			return;
		}

		// fuer xsl match
		String mainNamespacePrefix = null;

		// fuer xsl namespace
		String mainNamespaceUri = null;

		pElementGroup = printProject.getPElementGroup();
		if (pElementGroup == null) {
			stop = true;
			return;
		}
		if (pElementGroup.noPrefixCount() == 1) {
			mainNamespacePrefix = pElementGroup.getMainNamespacePrefix();
			mainNamespaceUri = pElementGroup.getMainNamespaceUri();
		}

		// formatGroup = styleData.getFormatGroup();
		mappingGroup = printProject.getMappingGroup();
		mappingGroup.setMainNamespacePrefix(mainNamespacePrefix);
		mappingGroup.setMainNamespaceUri(mainNamespaceUri);

		referencingSystemSetup.setPrintProject(printProject);
		referenceFieldSetup.setPrintProject(printProject);
		formatGroupSetup.setPrintProject(printProject);
		mappingGroupSetup.setPrintProject(printProject);
		pageMasterSetup.setPrintProject(printProject);
		innerLinkSetup.setPrintProject(printProject);
	}

	public void main(String[] args) {
		new StileditorViewer();
	}

	public void open() {
		initInput();
		if (stop) {
			return;
		}

		shell.setText(GuiMessages.Stileditor_Gui_Title + " Project: "
				+ printProject.getProject().getName());

		shell.open();

	}

	private void setFootComp(Shell shell) {
		final Composite footComp = new Composite(shell, SWT.BOTTOM);
		GridData footGridData = new GridData();
		footComp.setLayoutData(footGridData);
		footComp.setLayout(new FillLayout());
		Button saveChangesButton = new Button(footComp, SWT.NONE);
		saveChangesButton.setText(GuiMessages.Stileditor_Gui_SaveChanges);
		saveChangesButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (mappingGroup.containsEmptyFormat()) {
					MessageDialog.openError(null,
							GuiMessages.Stileditor_Error_Error,
							GuiMessages.Stileditor_Error_EmptyFormat);
					return;
				}
				RuntimeUtil rt = RuntimeUtil.getInstance();
				if (!rt.getCurrentPrintProject().updateWith(printProject)) {
					MessageDialog.openError(null,
							GuiMessages.Stileditor_Error_Error,
							"Error while updating PrintProject, ");
				}
				if (!rt.writeSettingXml(printProject)) {
					MessageDialog.openError(null,
							GuiMessages.Stileditor_Error_Error,
							"Error while writing settings.xml, ");
				}
				
				if (!rt.writeConfigurationXml(printProject)) {
					MessageDialog.openError(null,
							GuiMessages.Stileditor_Error_Error,
							"Error while writing configuration.xml");
				}
				footComp.getShell().close();
				WorkbenchInfo.focusEditor();
			}
		});

		Button previewButton = new Button(footComp, SWT.NONE);
		previewButton.setText(GuiMessages.General_Gui_Preview);
		previewButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {

				String editorText = RuntimeUtil.getInstance().getContentText(
						printProject);
				if (editorText != null) {
					// fo erzeugen mit xsl
					XML2Foplus pdfOut = new XML2Foplus(editorText, mappingGroup);
					pdfOut.setXslSour(mappingGroup.getXslDoc());

					// fo to pdf transformieren
					CmdToPDF ctp = new CmdToPDF();
					if (!ctp.isStop() && pdfOut.getResultFoFile() != null) {
						ctp.transform();
						ctp.pdfDisplay();
					}

				}
			}
		});

		Button verwerfenButton = new Button(footComp, SWT.NONE);
		verwerfenButton.setText(GuiMessages.Stileditor_Gui_DiscardChanges);
		verwerfenButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				footComp.getShell().close();
				// WorkbenchInfo.getActiveEditor().setFocus();
			}
		});

	}

	private void setMainMenu(Shell shell) {
		// Menu --------------------------------------------------------
		Menu mainMenu = new Menu(shell, SWT.BAR);
		shell.setMenuBar(mainMenu);
		MenuItem setupItem = new MenuItem(mainMenu, SWT.CASCADE);
		setupItem.setText(GuiMessages.General_Menu_Settings);

		//Menu setupSubMenu = new Menu(shell, SWT.DROP_DOWN);
		//setupItem.setMenu(setupSubMenu);
		//MenuItem pageItem = new MenuItem(setupSubMenu, SWT.CASCADE);
		//pageItem.setText(GuiMessages.Stileditor_PageLayout_Layout);

		/*pageItem.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event e) {
				if (pageLayoutSetup == null) {
					pageLayoutSetup = new PageLayoutSetup();
				}
				pageLayoutSetup.show(mappingGroup);
			}
		});*/

		// Hilfe
		Menu helpSubMenu = new Menu(shell, SWT.DROP_DOWN);
		MenuItem helpItem = new MenuItem(mainMenu, SWT.CASCADE);
		helpItem.setText(GuiMessages.General_Menu_Help);
		helpItem.setMenu(helpSubMenu);
		MenuItem infoItem = new MenuItem(helpSubMenu, SWT.CASCADE);
		infoItem.setText(GuiMessages.General_Menu_Info);

	}
}
